---
title: 媒体组件
docs:
  - route: /docs/components/media-image-node
    title: 图片元素
  - route: /docs/components/media-video-node
    title: 视频元素
  - route: /docs/components/media-audio-node
    title: 音频元素
  - route: /docs/components/media-file-node
    title: 文件元素
  - route: /docs/components/media-embed-node
    title: 媒体嵌入元素
  - route: /docs/components/media-toolbar
    title: 媒体弹出框
  - route: /docs/components/media-placeholder-node
    title: 媒体占位元素
  - route: /docs/components/media-upload-toast
    title: 媒体上传提示
  - route: /docs/components/media-toolbar-button
    title: 媒体工具栏按钮
  - route: https://pro.platejs.org/docs/examples/media
    title: 上传功能
  - route: https://pro.platejs.org/docs/components/media-toolbar
    title: 媒体工具栏
---

<ComponentPreview name="media-demo" />

<PackageInfo>

## 功能特性

### 媒体支持
- **文件类型**: 
  - 图片
  - 视频
  - 音频
  - 其他 (PDF, Word等)
- **视频平台**: 
  - 本地视频文件
  - YouTube, Vimeo, Dailymotion, Youku, Coub
- **嵌入支持**: 
  - 推特推文

### 媒体功能
- 可编辑的标题说明
- 可调整大小的元素

### 上传功能
- **多种上传方式**:
  - 工具栏按钮文件选择器
  - 从文件系统拖放
  - 从剪贴板粘贴(图片)
  - 外部媒体URL嵌入
- **上传体验**:
  - 实时进度跟踪
  - 上传过程中预览
  - 上传或嵌入完成后自动将占位符转换为相应的媒体元素(图片/视频/音频/文件)
  - 错误处理
  - 文件大小验证
  - 类型验证

</PackageInfo>

## 套件使用

<Steps>

### 安装

最快捷的媒体支持方式是使用`MediaKit`，它包含预配置的`ImagePlugin`、`VideoPlugin`、`AudioPlugin`、`FilePlugin`、`MediaEmbedPlugin`、`PlaceholderPlugin`和`CaptionPlugin`及其[Plate UI](/docs/installation/plate-ui)组件。

<ComponentSource name="media-kit" />

- [`ImageElement`](/docs/components/media-image-node): 渲染图片元素
- [`VideoElement`](/docs/components/media-video-node): 渲染视频元素
- [`AudioElement`](/docs/components/media-audio-node): 渲染音频元素
- [`FileElement`](/docs/components/media-file-node): 渲染文件元素
- [`MediaEmbedElement`](/docs/components/media-embed-node): 渲染嵌入媒体
- [`PlaceholderElement`](/docs/components/media-placeholder-node): 渲染上传占位符
- [`MediaUploadToast`](/docs/components/media-upload-toast): 显示上传进度通知
- [`MediaPreviewDialog`](/docs/components/media-preview-dialog): 提供媒体预览功能

### 添加套件

将套件添加到你的插件中:

```tsx
import { createPlateEditor } from 'platejs/react';
import { MediaKit } from '@/components/editor/plugins/media-kit';

const editor = createPlateEditor({
  plugins: [
    // ...其他插件
    ...MediaKit,
  ],
});
```

### 添加API路由

<ComponentInstallation name="media-uploadthing-api" inline />

### 环境配置

从[UploadThing](https://uploadthing.com/dashboard/settings)获取密钥并添加到`.env`:

```bash title=".env"
UPLOADTHING_TOKEN=xxx
```

</Steps>

## 手动使用

<Steps>

### 安装

```bash
npm install @platejs/media
```

### 添加插件

在创建编辑器时将媒体插件包含到Plate插件数组中。

```tsx
import {
  AudioPlugin,
  FilePlugin,
  ImagePlugin,
  MediaEmbedPlugin,
  PlaceholderPlugin,
  VideoPlugin,
} from '@platejs/media/react';
import { createPlateEditor } from 'platejs/react';

const editor = createPlateEditor({
  plugins: [
    // ...其他插件
    ImagePlugin,
    VideoPlugin,
    AudioPlugin,
    FilePlugin,
    MediaEmbedPlugin,
    PlaceholderPlugin,
  ],
});
```

### 配置插件

使用自定义组件和上传设置配置插件。

```tsx
import {
  AudioPlugin,
  FilePlugin,
  ImagePlugin,
  MediaEmbedPlugin,
  PlaceholderPlugin,
  VideoPlugin,
} from '@platejs/media/react';
import { KEYS } from 'platejs';
import { createPlateEditor } from 'platejs/react';
import { 
  AudioElement, 
  FileElement, 
  ImageElement, 
  MediaEmbedElement, 
  PlaceholderElement, 
  VideoElement 
} from '@/components/ui/media-nodes';
import { MediaUploadToast } from '@/components/ui/media-upload-toast';

const editor = createPlateEditor({
  plugins: [
    // ...其他插件
    ImagePlugin.withComponent(ImageElement),
    VideoPlugin.withComponent(VideoElement),
    AudioPlugin.withComponent(AudioElement),
    FilePlugin.withComponent(FileElement),
    MediaEmbedPlugin.withComponent(MediaEmbedElement),
    PlaceholderPlugin.configure({
      options: { disableEmptyPlaceholder: true },
      render: { afterEditable: MediaUploadToast, node: PlaceholderElement },
    }),
  ],
});
```

- `withComponent`: 为每种媒体类型分配自定义渲染组件
- `options.disableEmptyPlaceholder`: 无文件上传时禁止显示占位符
- `render.afterEditable`: 在编辑器外部渲染上传进度提示

### 标题支持

要启用媒体标题，添加[Caption Plugin](/docs/caption):

```tsx
import { CaptionPlugin } from '@platejs/caption/react';

const editor = createPlateEditor({
  plugins: [
    // ...其他插件
    // ...媒体插件
    CaptionPlugin.configure({
      options: {
        query: {
          allow: [KEYS.img, KEYS.video, KEYS.audio, KEYS.file, KEYS.mediaEmbed],
        },
      },
    }),
  ],
});
```

### 自定义上传实现

对于自定义上传实现，创建符合此接口的上传钩子:

```ts
interface UseUploadFileProps {
  onUploadComplete?: (file: UploadedFile) => void;
  onUploadError?: (error: unknown) => void;
  headers?: Record<string, string>;
  onUploadBegin?: (fileName: string) => void;
  onUploadProgress?: (progress: { progress: number }) => void;
  skipPolling?: boolean;
}

interface UploadedFile {
  key: string;    // 唯一标识符
  url: string;    // 上传文件的公开URL
  name: string;   // 原始文件名
  size: number;   // 文件大小(字节)
  type: string;   // MIME类型
}
```

使用S3预签名URL的示例实现:

```ts
export function useUploadFile({ 
  onUploadComplete, 
  onUploadError, 
  onUploadProgress 
}: UseUploadFileProps = {}) {
  const [uploadedFile, setUploadedFile] = useState<UploadedFile>();
  const [uploadingFile, setUploadingFile] = useState<File>();
  const [progress, setProgress] = useState(0);
  const [isUploading, setIsUploading] = useState(false);

  async function uploadFile(file: File) {
    setIsUploading(true);
    setUploadingFile(file);

    try {
      // 从后端获取预签名URL和最终URL
      const { presignedUrl, fileUrl, fileKey } = await fetch('/api/upload', {
        method: 'POST',
        body: JSON.stringify({
          filename: file.name,
          contentType: file.type,
        }),
      }).then(r => r.json());

      // 使用预签名URL上传到S3
      await axios.put(presignedUrl, file, {
        headers: { 'Content-Type': file.type },
        onUploadProgress: (progressEvent) => {
          const progress = (progressEvent.loaded / progressEvent.total) * 100;
          setProgress(progress);
          onUploadProgress?.({ progress });
        },
      });

      const uploadedFile = {
        key: fileKey,
        url: fileUrl,
        name: file.name,
        size: file.size,
        type: file.type,
      };

      setUploadedFile(uploadedFile);
      onUploadComplete?.(uploadedFile);
      
      return uploadedFile;
    } catch (error) {
      onUploadError?.(error);
      throw error;
    } finally {
      setProgress(0);
      setIsUploading(false);
      setUploadingFile(undefined);
    }
  }

  return {
    isUploading,
    progress,
    uploadFile,
    uploadedFile,
    uploadingFile,
  };
}
```

然后将你的自定义上传钩子与媒体组件集成:

```tsx
import { useUploadFile } from '@/hooks/use-upload-file'; // 你的自定义钩子

// 在你的PlaceholderElement组件中
export function PlaceholderElement({ className, children, element, ...props }) {
  const { uploadFile, isUploading, progress } = useUploadFile({
    onUploadComplete: (uploadedFile) => {
      // 将占位符替换为实际媒体元素
      const { url, type } = uploadedFile;
      
      // 将占位符转换为适当的媒体类型
      editor.tf.replace.placeholder({
        id: element.id,
        url,
        type: getMediaType(type), // image, video, audio, file
      });
    },
    onUploadError: (error) => {
      console.error('上传失败:', error);
      // 处理上传错误，可能显示提示
    },
  });

  // 当文件被拖放或选择时使用uploadFile
  // 这与PlaceholderPlugin的文件处理集成
}
```

### 添加工具栏按钮

你可以将[`MediaToolbarButton`](/docs/components/media-toolbar-button)添加到[Toolbar](/docs/toolbar)以上传和插入媒体。

### 插入工具栏按钮

你可以将这些项添加到[插入工具栏按钮](/docs/toolbar#insert-toolbar-button)来插入媒体元素:

```tsx
{
  icon: <ImageIcon />,
  label: '图片',
  value: KEYS.img,
}
```

</Steps>

## Plate Plus

<ComponentPreviewPro name="media-pro" />

## 插件

### `ImagePlugin`

用于void图片元素的插件。

<API name="ImagePlugin">
<APIOptions type="ImagePluginOptions">
  <APIItem name="uploadImage" type="(dataUrl: string | ArrayBuffer) => Promise<string | ArrayBuffer> | string | ArrayBuffer" optional>
    上传图片到服务器的函数。接收:
    - 来自`FileReader.readAsDataURL`的数据URL(字符串)
    - 来自剪贴板数据的ArrayBuffer
    返回:
    - 上传图片的URL字符串
    - 如果不需要上传则返回原始数据URL/ArrayBuffer
    - **默认:** 返回原始输入
  </APIItem>
  <APIItem name="disableUploadInsert" type="boolean" optional>
    禁用数据插入时的文件上传。
    - **默认:** `false`
  </APIItem>
  <APIItem name="disableEmbedInsert" type="boolean" optional>
    禁用数据插入时的URL嵌入。
    - **默认:** `false`
  </APIItem>
  <APIItem name="isUrl" type="function" optional>
    检查文本字符串是否为URL的函数。
  </APIItem>
  <APIItem name="transformUrl" type="function" optional>
    转换URL的函数。
  </APIItem>
</APIOptions>
</API>

### `VideoPlugin`

用于void视频元素的插件。扩展`MediaPluginOptions`。

### `AudioPlugin`

用于void音频元素的插件。扩展`MediaPluginOptions`。

### `FilePlugin`

用于void文件元素的插件。扩展`MediaPluginOptions`。

### `MediaEmbedPlugin`

用于void媒体嵌入元素的插件。扩展`MediaPluginOptions`。

### `PlaceholderPlugin`

管理上传过程中媒体占位符的插件。处理文件上传、拖放和剪贴板粘贴事件。

<API name="PlaceholderPlugin">
<APIOptions type="object">
  <APIItem name="uploadConfig" type="Partial<Record<AllowedFileType, MediaItemConfig>>" optional>
不同文件类型的配置。默认配置:
```ts
{
  audio: {
    maxFileCount: 1,
    maxFileSize: '8MB',
    mediaType: KEYS.audio,
    minFileCount: 1,
  },
  blob: {
    maxFileCount: 1,
    maxFileSize: '8MB',
    mediaType: KEYS.file,
    minFileCount: 1,
  },
  image: {
    maxFileCount: 3,
    maxFileSize: '4MB',
    mediaType: KEYS.image,
    minFileCount: 1,
  },
  pdf: {
    maxFileCount: 1,
    maxFileSize: '4MB',
    mediaType: KEYS.file,
    minFileCount: 1,
  },
  text: {
    maxFileCount: 1,
    maxFileSize: '64KB',
    mediaType: KEYS.file,
    minFileCount: 1,
  },
  video: {
    maxFileCount: 1,
    maxFileSize: '16MB',
    mediaType: KEYS.video,
    minFileCount: 1,
  },
}
```
支持的文件类型: `'image' | 'video' | 'audio' | 'pdf' | 'text' | 'blob'`
<APISubList>
  <APISubListItem parent="uploadConfig" name="mediaType" type="MediaKeys">
    此配置对应的媒体插件键: `'audio' | 'file' | 'image' | 'video'`
  </APISubListItem>
  <APISubListItem parent="uploadConfig" name="maxFileCount" type="number" optional>
    此类型文件可上传的最大数量。
  </APISubListItem>
  <APISubListItem parent="uploadConfig" name="maxFileSize" type="FileSize" optional>
    此类型文件的最大文件大小。格式: `${1|2|4|8|16|32|64|128|256|512|1024}${B|KB|MB|GB}`
  </APISubListItem>
  <APISubListItem parent="uploadConfig" name="minFileCount" type="number" optional>
    此类型文件必须上传的最小数量。
  </APISubListItem>
</APISubList>
</APIItem>
<APIItem name="disableEmptyPlaceholder" type="boolean" optional>
无文件上传时禁用空占位符。
- **默认:** `false`
</APIItem>
<APIItem name="disableFileDrop" type="boolean" optional>
禁用拖放文件上传功能。
- **默认:** `false`
</APIItem>
<APIItem name="maxFileCount" type="number" optional>
如果`uploadConfig`未指定，可一次上传的最大文件数。
- **默认:** `5`
</APIItem>
<APIItem name="multiple" type="boolean" optional>
允许上传多个相同类型的文件。
- **默认:** `true`
</APIItem>
</APIOptions>
</API>

## API

### `api.placeholder.addUploadingFile`

跟踪当前正在上传的文件。

<API name="addUploadingFile">
<APIParameters>
  <APIItem name="id" type="string">
    占位符元素的唯一标识符。
  </APIItem>
  <APIItem name="file" type="File">
    正在上传的文件。
  </APIItem>
</APIParameters>
</API>

### `api.placeholder.getUploadingFile`

获取当前正在上传的文件。

<API name="getUploadingFile">
<APIParameters>
  <APIItem name="id" type="string">
    占位符元素的唯一标识符。
  </APIItem>
</APIParameters>

<APIReturns>
  <APIItem type="File | undefined">
    如果找到则返回上传文件，否则返回undefined。
  </APIItem>
</APIReturns>
</API>

### `api.placeholder.removeUploadingFile`

上传完成或失败后从上传跟踪状态中移除文件。

<API name="removeUploadingFile">
<APIParameters>
  <APIItem name="id" type="string">
    要移除的占位符元素的唯一标识符。
  </APIItem>
</APIParameters>
</API>

## 转换方法

### `tf.insert.media`

使用上传占位符将媒体文件插入编辑器。

<API name="insertMedia">
<APIParameters>
  <APIItem name="files" type="FileList">
    要上传的文件。根据配置的文件类型和限制进行验证。
  </APIItem>
  <APIItem name="options" type="object" optional>
    插入节点的转换选项。
  </APIItem>
</APIParameters>

<APIOptions type="object">
  <APIItem name="at" type="Path" optional>
    插入媒体的位置。默认为当前选区。
  </APIItem>
  <APIItem name="nextBlock" type="boolean" optional>
    是否在媒体后插入新块。
    - **默认:** `true`
  </APIItem>
</APIOptions>
</API>

根据配置的限制(大小、数量、类型)验证文件，为每个文件创建占位符元素，处理多个文件顺序上传，维护撤销/重做操作的上传历史记录，如果验证失败则触发错误处理。

错误代码:
```ts
enum UploadErrorCode {
  INVALID_FILE_TYPE = 400,
  TOO_MANY_FILES = 402,
  INVALID_FILE_SIZE = 403,
  TOO_LESS_FILES = 405,
  TOO_LARGE = 413,
}
```

### `tf.insert.imagePlaceholder`

插入一个在上传完成后转换为图片元素的占位符。

### `tf.insert.videoPlaceholder`

插入一个在上传完成后转换为视频元素的占位符。

### `tf.insert.audioPlaceholder`

插入一个在上传完成后转换为音频元素的占位符。

### `tf.insert.filePlaceholder`

插入一个在上传完成后转换为文件元素的占位符。

### `tf.insert.image`

在编辑器中插入图片元素。

<API name="insertImage">
<APIParameters>
  <APIItem name="url" type="string | ArrayBuffer">
    图片的 URL 或 ArrayBuffer。
  </APIItem>
  <APIItem name="options" type="InsertNodesOptions" optional>
    插入图片元素的额外选项。
  </APIItem>
</APIParameters>

<APIOptions type="InsertImageOptions">
  <APIItem name="nextBlock" type="boolean" optional>
    如果为 true，图片将被插入到下一个块中。
  </APIItem>
</APIOptions>
</API>

### `tf.insert.mediaEmbed`

在当前选区插入媒体嵌入元素。

<API name="insertMediaEmbed">
<APIOptions type="InsertMediaEmbedOptions">
  <APIItem name="url" type="string" optional>
    媒体嵌入的 URL。
    - **默认值:** `''`
  </APIItem>
  <APIItem name="key" type="string" optional>
    媒体嵌入元素的键。
    - **默认值:** `KEYS.mediaEmbed`
  </APIItem>
  <APIItem name="insertNodesOptions" type="InsertNodesOptions" optional>
    插入节点的额外选项。
  </APIItem>
</APIOptions>
</API>

## Hooks

### `useResizable`

处理媒体元素的可调整大小属性。

<API name="useResizable">
<APIState>
  <APIItem name="align" type="'left' | 'center' | 'right'">
    可调整大小元素内容的对齐方式。
  </APIItem>
  <APIItem name="minWidth" type="ResizeLength">
    可调整大小元素可以调整到的最小宽度。
  </APIItem>
  <APIItem name="maxWidth" type="ResizeLength">
    可调整大小元素可以调整到的最大宽度。
  </APIItem>
  <APIItem name="setNodeWidth" type="(width: number | string) => void">
    调整大小时设置节点宽度的函数。
  </APIItem>
  <APIItem name="setWidth" type="(width: number | string) => void">
    直接设置可调整大小元素宽度的函数。
  </APIItem>
  <APIItem name="width" type="Property.Width<string | number> | undefined">
    可调整大小元素的当前宽度（百分比、'auto' 或像素）。
  </APIItem>
</APIState>

<APIReturns type="object">
  <APIItem name="wrapperRef" type="React.RefObject<HTMLDivElement>">
    最外层包装 div 的 React 引用。
  </APIItem>
  <APIItem name="wrapperProps.style" type="CSSProperties">
    包装 div 的 CSS 样式。
  </APIItem>
  <APIItem name="props.style" type="CSSProperties">
    可调整大小元素的 CSS 样式。
  </APIItem>
  <APIItem name="context.onResize" type="() => void">
    元素调整大小时调用的回调函数。
  </APIItem>
</APIReturns>
</API>

### `useMediaState`

媒体元素的状态钩子。

<API name="useMediaState">
<APIParameters>
  <APIItem name="options.urlParsers" type="EmbedUrlParser[]" optional>
    用于解析媒体元素 URL 的 URL 解析器数组。
  
    - **`EmbedUrlParser`:** `(url: string) => EmbedUrlData | undefined`
  </APIItem>
</APIParameters>

<APIReturns type="object">
  <APIItem name="align" type="string">
    媒体元素的对齐方式。
  </APIItem>
  <APIItem name="focus" type="boolean">
    媒体元素是否当前获得焦点。
  </APIItem>
  <APIItem name="selected" type="boolean">
    媒体元素是否当前被选中。
  </APIItem>
  <APIItem name="readOnly" type="boolean">
    编辑器是否处于只读模式。
  </APIItem>
  <APIItem name="embed" type="EmbedUrlData">
    媒体元素的解析嵌入数据。
  </APIItem>
  <APIItem name="isTweet" type="boolean">
    媒体元素是否为推文。
  </APIItem>
  <APIItem name="isVideo" type="boolean">
    媒体元素是否为视频。
  </APIItem>
  <APIItem name="isYoutube" type="boolean">
    媒体元素是否为 YouTube 视频。
  </APIItem>
</APIReturns>
</API>

### `useMediaToolbarButton`

媒体工具栏按钮的行为钩子。

<API name="useMediaToolbarButton">
<APIParameters>
  <APIItem name="options.nodeType" type="string" optional>
    要插入的媒体节点类型。
  </APIItem>
</APIParameters>

<APIReturns type="object">
  <APIItem name="props.onClick" type="() => void">
    插入媒体节点并使编辑器获得焦点的回调函数。
  </APIItem>
</APIReturns>
</API>

### `useFloatingMediaEditButton`

处理浮动媒体编辑按钮。

<API name="useFloatingMediaEditButton">
<APIReturns type="object">
  <APIItem name="props.onClick" type="() => void">
    处理按钮点击的回调函数。
  </APIItem>
</APIReturns>
</API>

### `useFloatingMediaUrlInput`

处理媒体元素的 URL 输入字段。

<API name="useFloatingMediaUrlInput">
<APIProps>
  <APIItem name="defaultValue" type="string">
    URL 输入字段的默认值。
  </APIItem>
</APIProps>

<APIReturns type="object">
  <APIItem name="props.onChange" type="() => void">
    处理输入变化的回调函数。
  </APIItem>
  <APIItem name="props.autoFocus" type="boolean">
    URL 输入字段是否应在挂载时获得焦点。
  </APIItem>
  <APIItem name="props.defaultValue" type="string">
    URL 输入字段的默认值。
  </APIItem>
</APIReturns>
</API>

### `useImage`

图片元素的钩子。

<API name="useImage">
<APIReturns type="object">
  <APIItem name="props.src" type="string">
    媒体元素的 URL。
  </APIItem>
  <APIItem name="props.alt" type="string">
    图片的说明文字。
  </APIItem>
  <APIItem name="props.draggable" type="boolean">
    图片是否可拖动。
  </APIItem>
</APIReturns>
</API>

## 工具函数

### `parseMediaUrl`

解析媒体 URL 以进行插件特定的处理。

<API name="parseMediaUrl">
<APIParameters>
  <APIItem name="options.pluginKey" type="string">
    媒体插件的键。
  </APIItem>
  <APIItem name="options.url" type="string" optional>
    要解析的媒体 URL。
  </APIItem>
</APIParameters>
</API>

### `parseVideoUrl`

解析视频 URL 并提取视频 ID 和提供商特定的嵌入 URL。

<API name="parseVideoUrl">
<APIParameters>
  <APIItem name="url" type="string">
    要解析的视频 URL。
  </APIItem>
</APIParameters>

<APIReturns type="EmbedUrlData | undefined">
  如果解析成功，返回包含视频 ID 和提供商的对象；如果 URL 无效或不支持，则返回 undefined。
</APIReturns>
</API>

### `parseTwitterUrl`

解析 Twitter URL 并提取推文 ID。

<API name="parseTwitterUrl">
<APIParameters>
  <APIItem name="url" type="string">
    Twitter URL。
  </APIItem>
</APIParameters>

<APIReturns>
  <APIItem type="EmbedUrlData | undefined">
    如果解析成功，返回包含推文 ID 和提供商的对象。
    如果 URL 无效或不匹配任何支持的视频提供商，则返回 undefined。
  </APIItem>
</APIReturns>
</API>

### `parseIframeUrl`

解析 iframe 嵌入的 URL。

<API name="parseIframeUrl">
<APIParameters>
  <APIItem name="url" type="string">
    iframe 的 URL 或嵌入代码。
  </APIItem>
</APIParameters>
</API>

### `isImageUrl`

检查 URL 是否为有效的图片 URL。

<API name="isImageUrl">
<APIParameters>
  <APIItem name="url" type="string">
    要检查的 URL。
  </APIItem>
</APIParameters>

<APIReturns type="boolean">
  URL 是否为有效的图片 URL。
</APIReturns>
</API>

### `submitFloatingMedia`

提交浮动媒体元素。

<API name="submitFloatingMedia">
<APIParameters>
  <APIItem name="options.element" type="TMediaElement">
    要提交的浮动媒体元素。
  </APIItem>
  <APIItem name="options.pluginKey" type="string" optional>
    媒体插件的键。
  </APIItem>
</APIParameters>
</API>

### `withImageUpload`

为编辑器实例添加图片上传功能。

<API name="withImageUpload">
<APIParameters>
  <APIItem name="plugin" type="PlatePlugin">
    Plate 插件。
  </APIItem>
</APIParameters>
</API>

### `withImageEmbed`

为编辑器实例添加图片相关功能。

<API name="withImageEmbed">
<APIParameters>
  <APIItem name="plugin" type="PlatePlugin">
    Plate 插件。
  </APIItem>
</APIParameters>
</API>

## 类型

### `TMediaElement`

```tsx
export interface TMediaElement extends TElement {
  url: string;
  id?: string;
  align?: 'center' | 'left' | 'right';
  isUpload?: boolean;
  name?: string;
  placeholderId?: string;
}
```

### `TPlaceholderElement`

```tsx
export interface TPlaceholderElement extends TElement {
  mediaType: string;
}
```

### `EmbedUrlData`

```tsx
export interface EmbedUrlData {
  url?: string;
  provider?: string;
  id?: string;
  component?: React.FC<EmbedUrlData>;
}
```